// 表单逻辑
import { validateFormLogic } from "../../utils/expression";
import { isLabelTag } from "@/views/formgen/components/GenerateForm/FormItemLabel";
import { BasicComponent } from "@/views/formgen/components/GenerateForm/types/form";

/**
 * 逻辑项
 */
export interface LogicItem {
  // 触发的显示逻辑
  triggerList: TriggerItem[];
  // 满足的条件
  conditionList: ConditionItem[];
}

/**
 * 条件项
 */
export interface ConditionItem {
  // 关系
  relation: "AND" | "OR";
  // eq ne 等
  expression: string;
  // 表单字段id
  formItemId: string;
  // 字段值
  optionValue: number;
  // 子条件
  subConditions?: ConditionItem[]; // 子条件，支持嵌套
}

// 逻辑触发操作类型
export type ActionType = "show" | "jump" | "finish" | "showOption" | "checkOption";

/**
 * 触发项目
 */
interface TriggerItem {
  // 触发类型
  type: ActionType;
  //表单字段id
  formItemId: string;
  // 如果是显示选项会是选项的值
  optionValue?: any;
}

// 逻辑条件配置
export interface ConditionGroup {
  // 条件列表
  conditionList: ConditionItem[];
  // 用来归类 显示 跳转 结束需要区分合并
  type?: ActionType;
}

// 具体条件格式
export type ConcreteCondition = {
  when: string; // 字段ID
  operator: string; // 操作符
  value: any; // 值
};

// 表达式结构（可嵌套）
export type VisibilityExpr = { and: VisibilityExpr[] } | { or: VisibilityExpr[] } | { not: VisibilityExpr } | ConcreteCondition;

// 操作级别枚举
export enum LogicLevel {
  FIELD = "field", // 字段级别
  OPTION = "option" // 选项级别
}

// 操作类型枚举
export enum LogicOperation {
  SHOW = "show", // 显示
  CHECK = "check" // 选中
}

export type LogicRule = {
  showConditions: ConditionGroup[]; // 合并后的显示条件
  dependentFields: string[]; // 受此字段影响的条件字段
  visibilityExpr?: VisibilityExpr; // 转换后的可见性表达式
  // 新增字段
  level: LogicLevel; // 操作级别：字段级别还是选项级别
  operation: LogicOperation; // 操作类型：显示还是选中
};

// 逻辑规则映射 显示字段id => 逻辑规则 如果是选项的话会是选项的 id
export type LogicRuleMap = Record<string, LogicRule>;

/**
 * 解析表单逻辑
 * @param data 表单逻辑数据
 * @param allFormItems 全部字段
 */
export function parserFormLogic(data: { formLogic: { scheme: LogicItem[] } }, allFormItems: BasicComponent[]) {
  let logicItemList = data.formLogic ? data.formLogic.scheme : [];
  const allFormItemIds = allFormItems.filter(item => !item.hideType).map(item => item.vModel);
  return buildFieldRulesMap(logicItemList, allFormItemIds, allFormItems);
}

/**
 * 将条件列表转换为逻辑表达式树
 * @param conditionList 条件列表
 * @returns VisibilityExpr 可见性表达式
 */
function convertConditionListToExpr(conditionList: ConditionItem[]): VisibilityExpr {
  if (!conditionList || conditionList.length === 0) {
    return { when: "", operator: "", value: null };
  }

  // 使用第一个条件的relation作为组合方式
  const relation = conditionList[0].relation;

  // 将ConditionItem转换为ConcreteCondition
  const convertToConcreteCondition = (item: ConditionItem): ConcreteCondition => ({
    when: item.formItemId,
    operator: item.expression,
    value: item.optionValue
  });

  if (conditionList.length === 1) {
    return convertToConcreteCondition(conditionList[0]);
  }

  // 根据relation决定使用and还是or
  return relation === "AND"
    ? { and: conditionList.map(convertToConcreteCondition) }
    : { or: conditionList.map(convertToConcreteCondition) };
}

/**
 * 将条件组转换为标准的逻辑表达式树结构
 * @param showConditions 显示条件列表
 * @param finishConditions 结束条件列表
 * @param jumpConditions 跳转条件列表
 * @returns VisibilityExpr 可见性表达式
 */
function buildVisibilityExpr(
  showConditions: ConditionGroup[],
  finishConditions: ConditionGroup[],
  jumpConditions: ConditionGroup[]
): VisibilityExpr {
  // 处理显示条件：多个show条件之间是OR关系
  const showExpr =
    showConditions.length > 0
      ? showConditions.length === 1
        ? convertConditionListToExpr(showConditions[0].conditionList)
        : { or: showConditions.map(c => convertConditionListToExpr(c.conditionList)) }
      : null;

  // 处理finish条件：多个finish条件之间是AND关系，每个条件都需要NOT
  const finishExpr =
    finishConditions.length > 0
      ? finishConditions.length === 1
        ? { not: convertConditionListToExpr(finishConditions[0].conditionList) }
        : { and: finishConditions.map(c => ({ not: convertConditionListToExpr(c.conditionList) })) }
      : null;

  // 处理jump条件：多个jump条件之间是AND关系，每个条件都需要NOT
  const jumpExpr =
    jumpConditions.length > 0
      ? jumpConditions.length === 1
        ? { not: convertConditionListToExpr(jumpConditions[0].conditionList) }
        : { and: jumpConditions.map(c => ({ not: convertConditionListToExpr(c.conditionList) })) }
      : null;

  // 组合所有表达式
  const validExprs = [showExpr, finishExpr, jumpExpr].filter(Boolean) as VisibilityExpr[];

  // 根据表达式数量构建最终的逻辑树
  if (validExprs.length === 0) {
    return { when: "", operator: "", value: null }; // 默认可见
  }
  if (validExprs.length === 1) {
    return validExprs[0];
  }

  // 如果有多个表达式，需要特殊处理NOT条件
  const notExprs: VisibilityExpr[] = [];
  const otherExprs: VisibilityExpr[] = [];

  validExprs.forEach(expr => {
    if ("not" in expr) {
      notExprs.push(expr);
    } else {
      otherExprs.push(expr);
    }
  });

  // 如果有多个NOT条件，将它们组合在一个AND中
  const combinedNotExpr = notExprs.length > 0 ? (notExprs.length === 1 ? notExprs[0] : { and: notExprs }) : null;

  // 组合最终表达式
  const finalExprs = [...otherExprs];
  if (combinedNotExpr) {
    finalExprs.push(combinedNotExpr);
  }

  return finalExprs.length === 1 ? finalExprs[0] : { and: finalExprs };
}

/**
 * 核心函数：根据逻辑规则构建规则集合
 */
function buildFieldRulesMap(logicJson: LogicItem[], allFormItemIds: string[], allFormItems: BasicComponent[]): LogicRuleMap {
  const ruleMap: LogicRuleMap = {};

  logicJson.forEach(rule => {
    const { triggerList, conditionList } = rule;

    triggerList.forEach(trigger => {
      const { type, formItemId, optionValue } = trigger;

      const updateRule = (id: string, type: ActionType) => {
        if (!ruleMap[id]) {
          ruleMap[id] = {
            showConditions: [],
            dependentFields: [],
            level: type === "showOption" || type === "checkOption" ? LogicLevel.OPTION : LogicLevel.FIELD,
            operation: type !== "checkOption" ? LogicOperation.SHOW : LogicOperation.CHECK
          };
        }

        // 合并条件
        ruleMap[id].showConditions.push({
          conditionList: conditionList,
          type: type
        });

        // 添加依赖字段
        conditionList.forEach(cond => {
          if (!ruleMap[id].dependentFields.includes(cond.formItemId)) {
            ruleMap[id].dependentFields.push(cond.formItemId);
          }
        });
      };

      if (type === "show") {
        updateRule(formItemId, type);
      } else if (type === "showOption" || type === "checkOption") {
        if (Array.isArray(optionValue)) {
          optionValue.forEach(([itemId, value]) => {
            const optionId = `${itemId}_${value}`;
            updateRule(optionId, type);
          });
        }
      } else if (type === "jump" || type === "finish") {
        // 先找到条件中最后一个字段的位置
        const lastCondFieldIndex = Math.max(
          ...conditionList.map(cond => allFormItemIds.indexOf(cond.formItemId)).filter(i => i >= 0)
        );
        const triggerIndex = formItemId ? allFormItemIds.indexOf(formItemId) : 0;

        if (lastCondFieldIndex === -1 || triggerIndex === -1) return;

        // 获取分页组件的位置
        const paginationIndices = allFormItems
          .map((item: BasicComponent, index: number) => (item.typeId === "PAGINATION" ? index : -1))
          .filter((i: number) => i >= 0);

        // jump: 从 lastCondField 到 trigger.formItemId 不包含目标这个字段，但不跳过分页
        // finish: 从 lastCondField 到最后一个字段，包括分页
        const endIndex = type === "jump" ? triggerIndex - 1 : allFormItemIds.length;
        let affectedFields = allFormItemIds.slice(lastCondFieldIndex + 1, endIndex);

        if (type === "jump") {
          // 对于跳题，我们需要过滤掉分页组件
          affectedFields = affectedFields.filter(fieldId => {
            const fieldIndex = allFormItemIds.indexOf(fieldId);
            return !paginationIndices.includes(fieldIndex);
          });
        }

        affectedFields.forEach(id => {
          updateRule(id, type);
        });
        // 如果是跳题逻辑 调到题目3 那么当条件满足时条件 3 应该是成立的 给题目 3 也加个显示逻辑
        if (type === "jump") {
          updateRule(formItemId, "show");
        }
      }
    });
  });

  // 将条件转换为VisibilityExpr结构
  Object.keys(ruleMap).forEach(fieldId => {
    const rule = ruleMap[fieldId];
    const showConditions = rule.showConditions.filter(
      c => c.type === "show" || c.type === "showOption" || c.type === "checkOption"
    );
    const finishConditions = rule.showConditions.filter(c => c.type === "finish");
    const jumpConditions = rule.showConditions.filter(c => c.type === "jump");

    rule.visibilityExpr = buildVisibilityExpr(showConditions, finishConditions, jumpConditions);
  });

  return ruleMap;
}

/**
 * 获取满足条件的表单数据
 * @param formData 表单数据
 * @param logicRuleMap 逻辑规则 使用buildFieldRulesMap构建
 *
 */
export function getFormLogicData(formData: Record<string, any>, logicRuleMap: LogicRuleMap) {
  // 获取不满足条件的字段
  const fieldsToDelete = new Set(getUnsatisfiedFields(formData, logicRuleMap));

  // 创建新的表单数据对象，排除不满足条件的字段
  const filteredFormData = { ...formData };
  fieldsToDelete.forEach(fieldId => {
    delete filteredFormData[fieldId];
  });

  return filteredFormData;
}

/**
 * 获取需要隐藏的字段Id列表
 * 根据数据进行逻辑判断
 * @param formData 表单数据
 * @param logicData 逻辑触发规则
 * @param allFields 全部字段
 */
export function getHiddenFormItemIds(
  formData: Record<string, any>,
  logicData: { scheme: LogicItem[] },
  allFields: BasicComponent[]
): string[] {
  // 修复类型问题，包装 logicData 以匹配 parserFormLogic 的参数类型

  const wrappedLogicData = { formLogic: logicData };
  const logicRuleMap = parserFormLogic(wrappedLogicData, allFields);
  console.log(logicRuleMap);
  // 没显示的字段
  const unsatisfiedFields = getUnsatisfiedFields(formData, logicRuleMap);
  // 避免getUnsatisfiedFields返回未知字段
  return allFields.filter(item => unsatisfiedFields.includes(item.vModel)).map(item => item.vModel);
}

/**
 * 获取不满足条件的字段列表
 * @param formData 表单数据
 * @param logicRuleMap 逻辑规则
 * @returns 不满足条件的字段ID列表
 */
export function getUnsatisfiedFields(formData: Record<string, any>, logicRuleMap: LogicRuleMap): string[] {
  const unsatisfiedFields = new Set<string>();

  // 遍历所有字段的规则
  Object.entries(logicRuleMap).forEach(([fieldId, rule]) => {
    // 如果字段有可见性表达式，检查条件是否满足
    if (rule.visibilityExpr) {
      const isVisible = validateFormLogic(formData, rule.visibilityExpr);
      if (!isVisible) {
        unsatisfiedFields.add(fieldId);
        // 如果是标签类型，同时添加对应的label字段
        if (isLabelTag(fieldId)) {
          unsatisfiedFields.add(fieldId + "label");
        }
      }
    }
  });

  return Array.from(unsatisfiedFields);
}
